package com.msk.common.wechatV3.service;

import com.msk.common.utils.StringUtils;
import com.msk.common.wechatV3.base.CommonOrder;
import com.msk.common.wechatV3.config.WxPayV3Config;
import com.msk.common.wechatV3.pojo.only.bo.placeorder.Amount;
import com.msk.common.wechatV3.pojo.only.bo.placeorder.Payer;
import com.msk.common.wechatV3.pojo.only.bo.placeorder.WxPayRequestBo;
import com.msk.common.wechatV3.pojo.only.vo.initiatepayment.WxPayResult;
import com.msk.common.wechatV3.util.WXSignV3Utils;
import com.msk.common.wechatV3.util.WxPayV3Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @desc: 微信支付V3服务
 * @author: dz
 * @date: 2022-05-09 11:59
 **/
@Service
public class WeixinPayV3Service {

    @Autowired
    private WxPayV3Config wxPayV3ConfigDefault;

    /**
     * 微信APP支付
     * @param commonOrder
     * @return
     * @throws Exception
     */
    public Map<String, Object> weixinAppPayV3(CommonOrder commonOrder) throws Exception {
        WxPayV3Config wxPayV3Config = this.getWxPayV3Config(commonOrder.getWxPayV3Config());
        Map<String, Object> result = new HashMap<String, Object>();
        String appid = wxPayV3Config.getAppId();// 微信开放平台审核通过的应用APPID
        String mchid = wxPayV3Config.getMchId();
        String out_trade_no = commonOrder.getOrderNo();
        String description = "订单编号：" + out_trade_no;// "测试微信支付0.01_2";
//        if (StringUtils.isNotEmpty(commonOrder.getOrderContent())) {
//            description += "，购买内容：" + commonOrder.getOrderContent();
//        }
        BigDecimal orderAmount = commonOrder.getOrderAmount();
        int total_fee = (int) (Math.round(orderAmount.doubleValue() * 100));
        String notify_url = commonOrder.getNotifyUrl();//通知地址
        String attach = commonOrder.getAttach();//附加数据
        String serial_no = wxPayV3Config.getSerialNumber();//证书序列号
        String privateKeyFilePath = wxPayV3Config.getWxPayPrivateKey();//私钥路径
        //订单金额信息
        Amount amount = new Amount();
        amount.setCurrency("CNY");
        amount.setTotal(total_fee);
        //下单请求参数
        WxPayRequestBo wxPayRequestBo = new WxPayRequestBo(appid,mchid,description,out_trade_no,notify_url,amount,attach);
        //V3需要先调用下单接口生成  预支付交易会话标识 prepay_id
        Map<String, String> stringStringMap = WxPayV3Util.v3PayGet(WXSignV3Utils.placeOrderUrl,wxPayRequestBo,mchid,serial_no,privateKeyFilePath);
        String prepayid = stringStringMap.get("prepay_id");
        if(StringUtils.isNull(prepayid)){
            String code = stringStringMap.get("code");
            String message = stringStringMap.get("message");
            result.put("code", "0");
            result.put("message", "错误代码：["+code+"],错误信息："+message);
            return result;
        }
        //V3的签名，使用字段appId、timeStamp、nonceStr、prepayid计算得出的签名值
        //签名需要 使用商户私钥对待签名串进行SHA256 with RSA签名，并对签名结果进行Base64编码得到签名值。
        WxPayResult wxPayResult = WxPayV3Util.wxTuneUp(prepayid, appid,mchid ,privateKeyFilePath);
        result.put("data", wxPayResult);
        result.put("code", "1");
        result.put("message", "发起支付成功");
        return result;
    }
    /**
     * 微信小程序支付
     * @param commonOrder
     * @return
     * @throws Exception
     */
    public Map<String, Object> weixinJsapiPayV3(CommonOrder commonOrder,String openid) throws Exception {
        WxPayV3Config wxPayV3Config = this.getWxPayV3Config(commonOrder.getWxPayV3Config());
        Map<String, Object> result = new HashMap<String, Object>();
        String appid = wxPayV3Config.getAppId();// 微信开放平台审核通过的应用APPID
        String mchid = wxPayV3Config.getMchId();
        String out_trade_no = commonOrder.getOrderNo();
        String description = "订单编号：" + out_trade_no;
//        if (StringUtils.isNotEmpty(commonOrder.getOrderContent())) {
//            description += "，购买内容：" + commonOrder.getOrderContent();
//        }
        BigDecimal orderAmount = commonOrder.getOrderAmount();
        int total_fee = (int) (Math.round(orderAmount.doubleValue() * 100));
        String notify_url = commonOrder.getNotifyUrl();//通知地址
        String attach = commonOrder.getAttach();//附加数据
        String serial_no = wxPayV3Config.getSerialNumber();//证书序列号
        String privateKeyFilePath = wxPayV3Config.getWxPayPrivateKey();//私钥路径
        //订单金额信息
        Amount amount = new Amount();
        amount.setCurrency("CNY");
        amount.setTotal(total_fee);
        Payer payer = new Payer();
        payer.setOpenid(openid);
        //下单请求参数
        WxPayRequestBo wxPayRequestBo = new WxPayRequestBo(appid,mchid,description,out_trade_no,notify_url,amount,payer,attach);
        //V3需要先调用下单接口生成  预支付交易会话标识 prepay_id
        Map<String, String> stringStringMap = WxPayV3Util.v3PayGet(WXSignV3Utils.jsPlaceOrderUrl,wxPayRequestBo,mchid,serial_no,privateKeyFilePath);
        String prepayid = stringStringMap.get("prepay_id");
        if(StringUtils.isNull(prepayid)){
            String code = stringStringMap.get("code");
            String message = stringStringMap.get("message");
            result.put("code", "0");
            result.put("message", "错误代码：["+code+"],错误信息："+message);
            return result;
        }
        //小程序V3的签名，使用字段appId、timeStamp、nonceStr、package计算得出的签名值
        //签名需要 使用商户私钥对待签名串进行SHA256 with RSA签名，并对签名结果进行Base64编码得到签名值。
        WxPayResult wxPayResult = WxPayV3Util.wxMpTuneUp(prepayid, appid,mchid ,privateKeyFilePath);
        result.put("data", wxPayResult);
        result.put("code", "1");
        result.put("message", "发起支付成功");
        return result;
    }

    /**
     * 动态获取微信支付配置
     * @return
     */
    public WxPayV3Config getWxPayV3Config(WxPayV3Config wxPayV3Config) {
        if (wxPayV3Config == null) {
            wxPayV3Config = wxPayV3ConfigDefault;
        }
        return wxPayV3Config;
    }

}
